package ckw.database.model;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.PostLoad;
import javax.persistence.PrePersist;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.annotations.Type;

import core.communication.electionConfiguration.AddEditElectionDetailsElectionConfiguration;
import core.communication.electionConfiguration.AddMemberElectionConfiguration;
import core.communication.electionConfiguration.AddNonResidentVoterElectionConfiguration;
import core.communication.electionConfiguration.AddResidentVoterElectionConfiguration;
import core.communication.electionConfiguration.CMember;
import core.communication.electionConfiguration.ElectionConfiguration;
import core.communication.electionConfiguration.RemoveElectionElectionConfiguration;
import core.communication.electionConfiguration.RemoveMemberElectionConfiguration;
import core.communication.electionConfiguration.RemoveNonResidentVoterElectionConfiguration;
import core.communication.electionConfiguration.RemoveResidentVoterElectionConfiguration;
import core.database.AbstractEntity;
import core.utils.Converter;

@Entity
@Table(name = "electionChanges")
public class ElectionChanges extends AbstractEntity {

	@Column(name = "uri")
	private String uri;

	@Column(name = "electionIdentificationField")
	private Long electionIdentificationField;

	@Column(name = "electionActionsXML")
	@Type(type = "text")
	private String electionActionsXML;

	@Transient
	private List<ElectionConfiguration> electionActions = new ArrayList<ElectionConfiguration>();

	public ElectionChanges() {
	}

	public ElectionChanges(String uri, Long electionIdentificationField) {
		super();
		this.uri = uri;
		this.electionIdentificationField = electionIdentificationField;
	}

	public void onPersist() {
		convertListsToXml();
	}

	@PrePersist
	private void convertListsToXml() {
		electionActionsXML = Converter.objectToXML(electionActions);
	}

	@SuppressWarnings("unchecked")
	@PostConstruct
	@PostLoad
	private void converList() {
		electionActions = (List<ElectionConfiguration>) Converter.xmlToObject(electionActionsXML);
	}

	public String getUri() {
		return uri;
	}

	public void setUri(String uri) {
		this.uri = uri;
	}

	public Long getElectionIdentificationField() {
		return electionIdentificationField;
	}

	public void setElectionIdentificationField(Long electionIdentificationField) {
		this.electionIdentificationField = electionIdentificationField;
	}

	public String getElectionActionsXML() {
		return electionActionsXML;
	}

	public void setElectionActionsXML(String electionActionsXML) {
		this.electionActionsXML = electionActionsXML;
	}

	public List<ElectionConfiguration> getElectionActions() {
		return electionActions;
	}

	public void setElectionActions(List<ElectionConfiguration> electionActions) {
		this.electionActions = electionActions;
	}

	public void addAddEditElectionDetailsAction(Election election) {
		electionActions.add(new AddEditElectionDetailsElectionConfiguration(election.getIdentificationField(), election.getName(), election.getDescription(), election.getStartDate(), election
				.getEndDate(), election.getCards()));
	}

	public void addRemoveElectionAction() {
		electionActions.add(new RemoveElectionElectionConfiguration(electionIdentificationField));
	}

	public void addAddMemberAction(String administratorToken, Member member) {
		CMember cMember = member.toCMemberWihtoutAdministratorToken();
		cMember.setAdministratorToken(administratorToken);

		electionActions.add(new AddMemberElectionConfiguration(electionIdentificationField, cMember));
	}

	public void addRemoveMemberAction(String memberIdentificationField) {
		electionActions.add(new RemoveMemberElectionConfiguration(electionIdentificationField, memberIdentificationField));
	}

	public void addAddResidentVoterAction(Voter voter) {
		electionActions.add(new AddResidentVoterElectionConfiguration(electionIdentificationField, voter.toCVoter()));
	}

	public void addRemoveResidentVoterAction(String voterIdentificationField) {
		electionActions.add(new RemoveResidentVoterElectionConfiguration(electionIdentificationField, voterIdentificationField));
	}

	public void addAddNonResidentVoterAction(Voter voter) {
		electionActions.add(new AddNonResidentVoterElectionConfiguration(electionIdentificationField, voter.toCVoter()));
	}

	public void addRemoveNonResidentVoterAction(String voterIdentificationField) {
		electionActions.add(new RemoveNonResidentVoterElectionConfiguration(electionIdentificationField, voterIdentificationField));
	}

	@Override
	public String toString() {
		String output = "ElectionChanges dla Election: " + getElectionIdentificationField() + " i Noda: " + getUri() + "\n";
		for (ElectionConfiguration electionConfiguration : electionActions) {
			output += " * " + electionConfiguration.toString() + "\n";
		}
		return output;
	}
}
